//实现一个生产者-消费者模型

//首先模拟实现阻塞队列
class Myblockingqueue{
     String[] queue = new String[100];
     //这些变量在下面代码中涉及判断及修改应该加volatile进行修饰
    private static volatile int head;
    private static volatile int tail;
    private static volatile int size;
    public  void put(String value) throws InterruptedException {
        synchronized (this) {
            //这里不止一个notify会唤醒线程，interrupted也会唤醒线程
            //但是interrupted唤醒线程后不能够保证队列还是满的
            //所以为了安全起见应该在被唤醒后再进行一次判断所以应该将if判断改成while判断
//            if(queue.length==size){
//                //队列是满的则进入阻塞状态
//                this.wait();
//                return;
//            }
            while(queue.length==size){
                //队列是满的则进入阻塞状态
                this.wait();
//                return;
            }
            queue[tail] = value;
            tail++;
            //环形数组
            if(tail==queue.length){
                tail = 0;
            }
            size++;
            this.notify();
        }
    }
    public  String take() throws InterruptedException{
        synchronized (this) {
            //这里不止一个notify会唤醒线程，interrupted也会唤醒线程
            //但是interrupted唤醒线程后不能够保证队列还是空的
            //所以为了安全起见应该在被唤醒后再进行一次判断所以应该将if判断改成while判断
//            if(size==0){
//                //如果队列是空的则进入阻塞状态
//                this.wait();
//                return null;
//            }
            while (size==0){
                //如果队列是空的则进入阻塞状态
                this.wait();
//                return null;
            }
            String ret = queue[head];
            head++;
            //环形数组
            if(head==queue.length){
                head = 0;
            }
            size--;
            this.notify();
            return ret;
        }
    }
}

public class demo2 {
    public static void main(String[] args) {
        Myblockingqueue myblockingqueue = new Myblockingqueue();
        //两个线程：一个生产者，一个消费者
        Thread t1 = new Thread(() ->{
            int num = 1;
            while (true) {
                try {
                    myblockingqueue.put(""+num);
                    System.out.println("生产："+num);
                    num++;
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        Thread t2 = new Thread(() ->{
            while (true){
                try {
                    String ret = myblockingqueue.take();
                    System.out.println("消费：             "+ret);
                    Thread.sleep(500);

                } catch (InterruptedException e) {
                     throw new RuntimeException(e);
                }
            }
        });
        t1.start();
        t2.start();
    }



}
